// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using ILCompiler.DependencyAnalysis.RiscV64;

namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
    /// <summary>
    /// This node emits a thunk calling DelayLoad_Helper with a given instance signature
    /// to populate its indirection cell.
    /// </summary>
    public partial class ImportThunk
    {
        protected override void EmitCode(NodeFactory factory, ref RiscV64Emitter instructionEncoder, bool relocsOnly)
        {
            if (_thunkKind == Kind.Eager)
            {
                instructionEncoder.EmitJMP(_helperCell);
                return;
            }

            if (relocsOnly)
            {
                // When doing relocs only, we don't need to generate the actual instructions
                // as they will be ignored. Just emit the module import load and jump so we record the dependencies.
                instructionEncoder.EmitLD(Register.X11, factory.ModuleImport);
                instructionEncoder.EmitJMP(_helperCell);
                return;
            }

            switch (_thunkKind)
            {
                case Kind.Eager:
                    break;

                case Kind.DelayLoadHelper:
                case Kind.VirtualStubDispatch:
                {
                    // t5 contains indirection cell
                    // Do nothing t5 contains our first param

                    // li t0, #index
                    int index = _containingImportSection.IndexFromBeginningOfArray;
                    instructionEncoder.EmitLI(Register.X5, index);

                    // Move Module* -> t1
                    instructionEncoder.EmitLD(Register.X6, factory.ModuleImport);

                    break;
                }
                case Kind.Lazy:
                {
                    // Load Module* -> a1
                    instructionEncoder.EmitLD(Register.X11, factory.ModuleImport);
                    break;
                }
                default:
                    throw new NotImplementedException();
            }

            // branch to helper
            instructionEncoder.EmitJMP(_helperCell);
        }
    }
}
